--- /dev/null
+.expander-frame > * { border-top-width: 0; }
+.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported ExtensionsService */
-const { Gio, GLib } = imports.gi;
+const { Gdk, Gio, GLib, GObject, Gtk } = imports.gi;
+
+const ExtensionUtils = imports.misc.extensionUtils;
const { loadInterfaceXML } = imports.misc.fileUtils;
const { ServiceImplementation } = imports.dbusService;
}
OpenExtensionPrefsAsync(params, invocation) {
- this._proxy.OpenExtensionPrefsRemote(...params, (res, error) => {
+ const [uuid, parentWindow_, options] = params;
+
+ this._proxy.GetExtensionInfoRemote(uuid, (res, error) => {
if (this._handleError(invocation, error))
return;
+ const [serialized] = res;
+ const extension = ExtensionUtils.deserializeExtension(serialized);
+
+ const window = new ExtensionPrefsDialog(extension);
+
+ if (options.modal)
+ window.modal = options.modal.get_boolean();
+
+ window.connect('destroy', () => this.release());
+ this.hold();
+
+ window.show();
+
invocation.return_value(null);
});
}
});
}
};
+
+var ExtensionPrefsDialog = GObject.registerClass({
+ GTypeName: 'ExtensionPrefsDialog',
+ Template: 'resource:///org/gnome/Shell/Extensions/ui/extension-prefs-dialog.ui',
+ InternalChildren: [
+ 'headerBar',
+ 'stack',
+ 'expander',
+ 'expanderArrow',
+ 'revealer',
+ 'errorView',
+ ],
+}, class ExtensionPrefsDialog extends Gtk.Window {
+ _init(extension) {
+ super._init();
+
+ this._uuid = extension.uuid;
+ this._url = extension.metadata.url || '';
+
+ this._headerBar.title = extension.metadata.name;
+
+ this._actionGroup = new Gio.SimpleActionGroup();
+ this.insert_action_group('win', this._actionGroup);
+
+ this._initActions();
+ this._addCustomStylesheet();
+
+ this._gesture = new Gtk.GestureMultiPress({
+ widget: this._expander,
+ button: 0,
+ exclusive: true,
+ });
+
+ this._gesture.connect('released', (gesture, nPress) => {
+ if (nPress === 1)
+ this._revealer.reveal_child = !this._revealer.reveal_child;
+ });
+
+ this._revealer.connect('notify::reveal-child', () => {
+ this._expanderArrow.icon_name = this._revealer.reveal_child
+ ? 'pan-down-symbolic'
+ : 'pan-end-symbolic';
+ });
+
+ try {
+ ExtensionUtils.installImporter(extension);
+
+ // give extension prefs access to their own extension object
+ ExtensionUtils.getCurrentExtension = () => extension;
+
+ const prefsModule = extension.imports.prefs;
+ prefsModule.init(extension.metadata);
+
+ const widget = prefsModule.buildPrefsWidget();
+ this._stack.add(widget);
+ this._stack.visible_child = widget;
+ } catch (e) {
+ this._setError(e);
+ }
+ }
+
+ _setError(exc) {
+ this._errorView.buffer.text = `${exc}\n\nStack trace:\n`;
+ // Indent stack trace.
+ this._errorView.buffer.text +=
+ exc.stack.split('\n').map(line => ` ${line}`).join('\n');
+
+ // markdown for pasting in gitlab issues
+ let lines = [
+ `The settings of extension ${this._uuid} had an error:`,
+ '```',
+ `${exc}`,
+ '```',
+ '',
+ 'Stack trace:',
+ '```',
+ exc.stack.replace(/\n$/, ''), // stack without trailing newline
+ '```',
+ '',
+ ];
+ this._errorMarkdown = lines.join('\n');
+ this._actionGroup.lookup('copy-error').enabled = true;
+ }
+
+ _initActions() {
+ let action;
+
+ action = new Gio.SimpleAction({
+ name: 'copy-error',
+ enabled: false,
+ });
+ action.connect('activate', () => {
+ const clipboard = Gtk.Clipboard.get_default(this.get_display());
+ clipboard.set_text(this._errorMarkdown, -1);
+ });
+ this._actionGroup.add_action(action);
+
+ action = new Gio.SimpleAction({
+ name: 'show-url',
+ enabled: this._url !== '',
+ });
+ action.connect('activate', () => {
+ Gio.AppInfo.launch_default_for_uri(this._url,
+ this.get_display().get_app_launch_context());
+ });
+ this._actionGroup.add_action(action);
+ }
+
+ _addCustomStylesheet() {
+ let provider = new Gtk.CssProvider();
+ let uri = 'resource:///org/gnome/Shell/Extensions/css/application.css';
+ try {
+ provider.load_from_file(Gio.File.new_for_uri(uri));
+ } catch (e) {
+ logError(e, 'Failed to add application style');
+ }
+ Gtk.StyleContext.add_provider_for_screen(Gdk.Screen.get_default(),
+ provider,
+ Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+});
/* exported main */
+imports.gi.versions.Gdk = '3.0';
+imports.gi.versions.Gtk = '3.0';
+
+const { Gtk } = imports.gi;
+const pkg = imports.package;
+
const { DBusService } = imports.dbusService;
const { ExtensionsService } = imports.extensionsService;
function main() {
+ Gtk.init(null);
+ pkg.initFormat();
+
const service = new DBusService(
'org.gnome.Shell.Extensions',
new ExtensionsService());
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.22.1 -->
+<interface>
+ <requires lib="gtk+" version="3.20"/>
+ <template class="ExtensionPrefsDialog" parent="GtkWindow">
+ <property name="default_width">600</property>
+ <property name="default_height">400</property>
+ <child type="titlebar">
+ <object class="GtkHeaderBar" id="headerBar">
+ <property name="visible">True</property>
+ <property name="show_close_button">True</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStack" id="stack">
+ <property name="visible">True</property>
+ <property name="can_focus">False</property>
+ <child>
+ <object class="GtkScrolledWindow">
+ <property name="visible">True</property>
+ <property name="hscrollbar_policy">never</property>
+ <property name="propagate_natural_height">True</property>
+ <child>
+ <object class="GtkViewport">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="margin">100</property>
+ <property name="margin_bottom">60</property>
+ <property name="spacing">12</property>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Something’s gone wrong</property>
+ <attributes>
+ <attribute name="scale" value="1.44"/> <!-- x-large -->
+ </attributes>
+ <style>
+ <class name="dim-label"/>
+ </style>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">We’re very sorry, but there’s been a problem: the settings for this extension can’t be displayed. We recommend that you report the issue to the extension authors.</property>
+ <property name="justify">center</property>
+ <property name="wrap">True</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <property name="margin_top">12</property>
+ <child>
+ <object class="GtkFrame" id="expander">
+ <property name="visible">True</property>
+ <property name="hexpand">True</property>
+ <property name="shadow_type">in</property>
+ <child>
+ <object class="GtkEventBox">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="margin">12</property>
+ <property name="spacing">6</property>
+ <child>
+ <object class="GtkImage" id="expanderArrow">
+ <property name="visible">True</property>
+ <property name="icon_name">pan-end-symbolic</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkLabel">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Technical Details</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkRevealer" id="revealer">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkFrame">
+ <property name="visible">True</property>
+ <property name="shadow_type">in</property>
+ <style>
+ <class name="expander-frame"/>
+ </style>
+ <child>
+ <object class="GtkBox">
+ <property name="visible">True</property>
+ <property name="orientation">vertical</property>
+ <child>
+ <object class="GtkTextView" id="errorView">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="monospace">True</property>
+ <property name="editable">False</property>
+ <property name="wrap_mode">word</property>
+ <property name="left_margin">12</property>
+ <property name="right_margin">12</property>
+ <property name="top_margin">12</property>
+ <property name="bottom_margin">12</property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkToolbar">
+ <property name="visible">True</property>
+ <style>
+ <class name="expander-toolbar"/>
+ </style>
+ <child>
+ <object class="GtkToolItem">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkButton">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="action_name">win.copy-error</property>
+ <style>
+ <class name="flat"/>
+ <class name="image-button"/>
+ </style>
+ <child>
+ <object class="GtkImage">
+ <property name="visible">True</property>
+ <property name="icon_name">edit-copy-symbolic</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
+ <object class="GtkSeparatorToolItem">
+ <property name="visible">True</property>
+ <property name="draw">False</property>
+ </object>
+ <packing>
+ <property name="expand">True</property>
+ </packing>
+ </child>
+ <child>
+ <object class="GtkToolItem">
+ <property name="visible">True</property>
+ <child>
+ <object class="GtkButton" id="homeButton">
+ <property name="visible"
+ bind-source="homeButton"
+ bind-property="sensitive"
+ bind-flags="sync-create"/>
+ <property name="label" translatable="yes">Homepage</property>
+ <property name="tooltip_text" translatable="yes">Visit extension homepage</property>
+ <property name="can_focus">True</property>
+ <property name="receives_default">True</property>
+ <property name="no_show_all">True</property>
+ <property name="action_name">win.show-url</property>
+ <style>
+ <class name="flat"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </child>
+ </template>
+</interface>
<file>dbusService.js</file>
<file>misc/config.js</file>
+ <file>misc/extensionUtils.js</file>
<file>misc/fileUtils.js</file>
</gresource>
+
+ <gresource prefix="/org/gnome/Shell/Extensions">
+ <file>css/application.css</file>
+ <file>ui/extension-prefs-dialog.ui</file>
+ </gresource>
</gresources>
}
image.warning { color: @warning_color; }
-
-.expander-frame > * { border-top-width: 0; }
-.expander-toolbar { border: 0 solid @borders; border-top-width: 1px; }
<file>dbus-interfaces/org.gnome.Shell.Extensions.xml</file>
- <file>ui/extension-prefs-dialog.ui</file>
<file>ui/extension-row.ui</file>
<file>ui/extensions-window.ui</file>
</gresource>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.22.1 -->
-<interface>
- <requires lib="gtk+" version="3.20"/>
- <template class="ExtensionPrefsDialog" parent="GtkWindow">
- <property name="default_width">600</property>
- <property name="default_height">400</property>
- <child type="titlebar">
- <object class="GtkHeaderBar" id="headerBar">
- <property name="visible">True</property>
- <property name="show_close_button">True</property>
- </object>
- </child>
- <child>
- <object class="GtkStack" id="stack">
- <property name="visible">True</property>
- <property name="can_focus">False</property>
- <child>
- <object class="GtkScrolledWindow">
- <property name="visible">True</property>
- <property name="hscrollbar_policy">never</property>
- <property name="propagate_natural_height">True</property>
- <child>
- <object class="GtkViewport">
- <property name="visible">True</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="margin">100</property>
- <property name="margin_bottom">60</property>
- <property name="spacing">12</property>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Something’s gone wrong</property>
- <attributes>
- <attribute name="scale" value="1.44"/> <!-- x-large -->
- </attributes>
- <style>
- <class name="dim-label"/>
- </style>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">We’re very sorry, but there’s been a problem: the settings for this extension can’t be displayed. We recommend that you report the issue to the extension authors.</property>
- <property name="justify">center</property>
- <property name="wrap">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- </object>
- </child>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <property name="margin_top">12</property>
- <child>
- <object class="GtkFrame" id="expander">
- <property name="visible">True</property>
- <property name="hexpand">True</property>
- <property name="shadow_type">in</property>
- <child>
- <object class="GtkEventBox">
- <property name="visible">True</property>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="margin">12</property>
- <property name="spacing">6</property>
- <child>
- <object class="GtkImage" id="expanderArrow">
- <property name="visible">True</property>
- <property name="icon_name">pan-end-symbolic</property>
- </object>
- </child>
- <child>
- <object class="GtkLabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Technical Details</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkRevealer" id="revealer">
- <property name="visible">True</property>
- <child>
- <object class="GtkFrame">
- <property name="visible">True</property>
- <property name="shadow_type">in</property>
- <style>
- <class name="expander-frame"/>
- </style>
- <child>
- <object class="GtkBox">
- <property name="visible">True</property>
- <property name="orientation">vertical</property>
- <child>
- <object class="GtkTextView" id="errorView">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="monospace">True</property>
- <property name="editable">False</property>
- <property name="wrap_mode">word</property>
- <property name="left_margin">12</property>
- <property name="right_margin">12</property>
- <property name="top_margin">12</property>
- <property name="bottom_margin">12</property>
- </object>
- </child>
- <child>
- <object class="GtkToolbar">
- <property name="visible">True</property>
- <style>
- <class name="expander-toolbar"/>
- </style>
- <child>
- <object class="GtkToolItem">
- <property name="visible">True</property>
- <child>
- <object class="GtkButton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="action_name">win.copy-error</property>
- <style>
- <class name="flat"/>
- <class name="image-button"/>
- </style>
- <child>
- <object class="GtkImage">
- <property name="visible">True</property>
- <property name="icon_name">edit-copy-symbolic</property>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- <child>
- <object class="GtkSeparatorToolItem">
- <property name="visible">True</property>
- <property name="draw">False</property>
- </object>
- <packing>
- <property name="expand">True</property>
- </packing>
- </child>
- <child>
- <object class="GtkToolItem">
- <property name="visible">True</property>
- <child>
- <object class="GtkButton" id="homeButton">
- <property name="visible"
- bind-source="homeButton"
- bind-property="sensitive"
- bind-flags="sync-create"/>
- <property name="label" translatable="yes">Homepage</property>
- <property name="tooltip_text" translatable="yes">Visit extension homepage</property>
- <property name="can_focus">True</property>
- <property name="receives_default">True</property>
- <property name="no_show_all">True</property>
- <property name="action_name">win.show-url</property>
- <style>
- <class name="flat"/>
- </style>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </object>
- </child>
- </template>
-</interface>
_init(params) {
super._init(params);
- this._prefsDialog = null;
this._updatesCheckId = 0;
this._mainBox.set_focus_vadjustment(this._scrolledWindow.vadjustment);
}
openPrefs(uuid) {
- if (this._prefsDialog)
- return;
-
- let row = this._findExtensionRow(uuid);
- this._prefsDialog = new ExtensionPrefsDialog(row);
- this._prefsDialog.set({ transient_for: this, modal: true });
-
- this._prefsDialog.connect('destroy', () => (this._prefsDialog = null));
-
- this._prefsDialog.show();
+ this._shellProxy.OpenExtensionPrefsRemote(uuid,
+ '',
+ { modal: new GLib.Variant('b', true) });
}
_showAbout() {
_canToggle() {
return this._extension.canChange;
}
-
- get prefsModule() {
- // give extension prefs access to their own extension object
- ExtensionUtils.getCurrentExtension = () => this._extension;
-
- if (!this._prefsModule) {
- ExtensionUtils.installImporter(this._extension);
-
- this._prefsModule = this._extension.imports.prefs;
- this._prefsModule.init(this._extension.metadata);
- }
-
- return this._prefsModule;
- }
-});
-
-var ExtensionPrefsDialog = GObject.registerClass({
- GTypeName: 'ExtensionPrefsDialog',
- Template: 'resource:///org/gnome/Extensions/ui/extension-prefs-dialog.ui',
- InternalChildren: [
- 'headerBar',
- 'stack',
- 'expander',
- 'expanderArrow',
- 'revealer',
- 'errorView',
- ],
-}, class ExtensionPrefsDialog extends Gtk.Window {
- _init(extension) {
- super._init();
-
- this._uuid = extension.uuid;
- this._url = extension.url;
-
- this._headerBar.title = extension.name;
-
- this._actionGroup = new Gio.SimpleActionGroup();
- this.insert_action_group('win', this._actionGroup);
-
- this._initActions();
-
- this._gesture = new Gtk.GestureMultiPress({
- widget: this._expander,
- button: 0,
- exclusive: true,
- });
-
- this._gesture.connect('released', (gesture, nPress) => {
- if (nPress === 1)
- this._revealer.reveal_child = !this._revealer.reveal_child;
- });
-
- this._revealer.connect('notify::reveal-child', () => {
- this._expanderArrow.icon_name = this._revealer.reveal_child
- ? 'pan-down-symbolic'
- : 'pan-end-symbolic';
- });
-
- try {
- const widget = extension.prefsModule.buildPrefsWidget();
- this._stack.add(widget);
- this._stack.visible_child = widget;
- } catch (e) {
- this._setError(e);
- }
- }
-
- _setError(exc) {
- this._errorView.buffer.text = '%s\n\nStack trace:\n'.format(exc);
- // Indent stack trace.
- this._errorView.buffer.text +=
- exc.stack.split('\n').map(line => ' %s'.format(line)).join('\n');
-
- // markdown for pasting in gitlab issues
- let lines = [
- 'The settings of extension %s had an error:'.format(this._uuid),
- '```', // '`' (xgettext throws up on odd number of backticks)
- exc.toString(),
- '```', // '`'
- '',
- 'Stack trace:',
- '```', // '`'
- exc.stack.replace(/\n$/, ''), // stack without trailing newline
- '```', // '`'
- '',
- ];
- this._errorMarkdown = lines.join('\n');
- this._actionGroup.lookup('copy-error').enabled = true;
- }
-
- _initActions() {
- let action;
-
- action = new Gio.SimpleAction({
- name: 'copy-error',
- enabled: false,
- });
- action.connect('activate', () => {
- const clipboard = Gtk.Clipboard.get_default(this.get_display());
- clipboard.set_text(this._errorMarkdown, -1);
- });
- this._actionGroup.add_action(action);
-
- action = new Gio.SimpleAction({
- name: 'show-url',
- enabled: this._url !== '',
- });
- action.connect('activate', () => {
- Gio.AppInfo.launch_default_for_uri(this._url,
- this.get_display().get_app_launch_context());
- });
- this._actionGroup.add_action(action);
- }
});
function initEnvironment() {
// -*- mode: js; js-indent-level: 4; indent-tabs-mode: nil -*-
/* exported GnomeShell, ScreenSaverDBus */
-const { Gio, GLib, Meta, Shell } = imports.gi;
+const { Gio, GLib, Meta } = imports.gi;
const Config = imports.misc.config;
const ExtensionDownloader = imports.ui.extensionDownloader;
this.OpenExtensionPrefs(uuid, '', {});
}
- OpenExtensionPrefs(uuid, _parentWindow, _options) {
- let appSys = Shell.AppSystem.get_default();
- let app = appSys.lookup_app('org.gnome.Extensions.desktop');
- let info = app.get_app_info();
- let timestamp = global.display.get_current_time_roundtrip();
- info.launch_uris([`extension:///${uuid}`],
- global.create_app_launch_context(timestamp, -1));
+ OpenExtensionPrefs(uuid, parentWindow, options) {
+ Gio.DBus.session.call(
+ 'org.gnome.Shell.Extensions',
+ '/org/gnome/Shell/Extensions',
+ 'org.gnome.Shell.Extensions',
+ 'OpenExtensionPrefs',
+ new GLib.Variant('(ssa{sv})', [uuid, parentWindow, options]),
+ null,
+ Gio.DBusCallFlags.NONE,
+ -1,
+ null,
+ (conn, res) => conn.call_finish(res));
}
ReloadExtension(uuid) {
data/org.gnome.Shell.desktop.in.in
data/org.gnome.shell.gschema.xml.in
data/org.gnome.Shell.PortalHelper.desktop.in.in
+js/dbusServices/extensions/ui/extension-prefs-dialog.ui
js/extensionPrefs/data/metainfo/org.gnome.Extensions.metainfo.xml.in
js/extensionPrefs/data/org.gnome.Extensions.desktop.in.in
js/extensionPrefs/js/main.js
-js/extensionPrefs/data/ui/extension-prefs-dialog.ui
js/extensionPrefs/data/ui/extension-row.ui
js/extensionPrefs/data/ui/extensions-window.ui
js/gdm/authPrompt.js